﻿//文件指定编译编码UTF-8
#pragma execution_character_set("utf-8")

/**
*    @file:    qsingleinstanceguard.cpp
*    @brief:
*    @author:  sanshi522@163.com
*    @date:    2025-01-06  15:24
*/
#include "qsingleinstanceguard.h"
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QLocalSocket>

#ifdef Q_OS_WIN
#include <windows.h>
#else
#include <fcntl.h>
#include <unistd.h>
#include <sys/file.h>
#include <semaphore.h>
#endif

QSingleInstanceGuard::QSingleInstanceGuard(const QString &appId, QObject *parent)
    : QObject(parent), m_appId(appId), m_localServer(nullptr)
{
    QSharedMemory sharedMemory(appId);
    if (!sharedMemory.create(1)) { // 1 字节足够用于标记
        if (sharedMemory.error() == QSharedMemory::AlreadyExists) {
            qDebug() << "共享内存已存在，说明另一个实例已经在运行";
            activateExistingInstance();
        } else {
            qDebug() << "创建共享内存失败:" << sharedMemory.errorString();
            return;
        }
    }else{
        qDebug() << "创建共享内存成功:" << appId << sharedMemory.data();
    }
    // 设置本地服务器以监听消息
    m_localServer = new QLocalServer(this);
    connect(m_localServer, &QLocalServer::newConnection, this, &QSingleInstanceGuard::onNewConnection);

    if (!m_localServer->listen(m_appId)) {
        qWarning() << "Failed to start local server:" << m_localServer->errorString();
        return;
    }
}

QSingleInstanceGuard::~QSingleInstanceGuard()
{
    if (m_sharedMemory.isAttached()) {
            m_sharedMemory.detach();
        }
    if (m_localServer) {
        m_localServer->close();
        delete m_localServer;
    }
}

bool QSingleInstanceGuard::isAnotherInstanceRunning()
{
    return m_sharedMemory.isAttached();
}


void QSingleInstanceGuard::sendMessageToExistingInstance(const QString &message)
{
    if (isAnotherInstanceRunning()) {
        QLocalSocket socket;
        socket.connectToServer(m_appId);
        if (socket.waitForConnected(5000)) {
            QTextStream out(&socket);
            out << message << endl;
            socket.flush();
            socket.waitForBytesWritten(5000);
            qInfo() << "Message sent to existing instance.";
        } else {
            qWarning() << "Failed to connect to existing server:" << socket.errorString();
        }
    }
}

void QSingleInstanceGuard::activateExistingInstance()
{
    sendMessageToExistingInstance("activate");
    qApp->quit(); // 退出当前实例
}

void QSingleInstanceGuard::onNewConnection()
{
    QLocalSocket *clientConnection = m_localServer->nextPendingConnection();
    connect(clientConnection, &QLocalSocket::readyRead, this, &QSingleInstanceGuard::onReadyRead);
    connect(clientConnection, &QLocalSocket::disconnected, clientConnection, &QLocalSocket::deleteLater);
}

void QSingleInstanceGuard::onReadyRead()
{
    QLocalSocket *clientConnection = qobject_cast<QLocalSocket*>(sender());
    if (clientConnection) {
        QByteArray data = clientConnection->readAll();
        QString message = QString::fromUtf8(data).trimmed();
        emit messageReceived(message);
        //        if (message == "activate") {
        //            handleActivationMessage();
        //        }
    }
}
